'''
Created on 2011-9-19

@author: Administrator
'''

from ftplib import FTP
import logging
import os
import resultparse
import resultparse.base
from sqlalchemy import *
import shutil 
import re
import sys

def UpdateCaseResult(downlaodcfg, templateid, taskid, casesql, dburl):
    
    casepath = os.path.join('casepath', "%d_%d" % (templateid, taskid))
    print(casepath)
    try:
        if os.path.exists(casepath):
            shutil.rmtree(casepath, True)
        os.mkdir(casepath)
    except  OSError as e:
        print(e)
        return
    
    logging.basicConfig(filename = os.path.join(casepath, 'task.log'), 
                                format='%(asctime)s %(levelname)-8s %(message)s',
                                datefmt='%Y%b%d %H:%M:%S')
   
        
    logging.getLogger().setLevel(logging.DEBUG)
    
    logging.info('task script begin run')
    
    engine = None
    result = None
    try:
        engine = create_engine(dburl)
        #logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
        result = engine.execute(casesql)
        needruncase = result.fetchall()
        testresult_t =  Table('TestResult', MetaData(engine), autoload = True)
        resultinsert = testresult_t.insert()
        cases = {}
        for v in needruncase:
            cases[v.Name] = v.Id
        filelist = DownloadResult(downlaodcfg, templateid, taskid, casepath)
        caselist = CaseResultParse(filelist)
        
        for v in caselist:
            if v.name in cases:
                v.id = cases.pop(v.name)
                resultinsert.execute(TaskId = taskid, CaseId = v.id, ResultStatusId = v.result, 
                                     Message = v.message,
                                     StartTime = v.start_time, EndTime = v.end_time)
        
        for v in cases:
            resultinsert.execute(TaskId = taskid, CaseId = cases[v], ResultStatusId = resultparse.base.NORUN)
    except Exception as e:
        logging.exception(e)
    finally:
        if result != None:
            result.close
        if engine != None:
            engine.dispose()
    logging.info('insert case result finish')

def FTPInit(ftpconfig):
    ftp = FTP()
    try:
        ftp.connect(ftpconfig.ip, ftpconfig.port)
        if ftpconfig.username and ftpconfig.password:
            ftp.login(ftpconfig.username, ftpconfig.password)
        ftp.getwelcome()
    except Exception as e:
        logging.exception(e)
        return None
    return ftp

def GetFileInDir(filelist, path, Ftp):
    fs = Ftp.nlst(path)
    for v in fs:
        if v == path:
            filelist.append(v)
        else:
            GetFileInDir(filelist, v, Ftp)

def DownloadResult(ftpconfig, templateid, taskid, resultpath):
    ftp  = FTPInit(ftpconfig)
    if ftp == None:
        return []
    
    downlaodlist = []
    filehandler = None
    try:
        ftp.cwd("%d_%d/case" % (templateid, taskid))
        filelist = []
        GetFileInDir(filelist, '', ftp)    
        index  = 1
        for v in filelist:
            name = os.path.basename(v) + '.' + str(index)
            filehandler = open(os.path.join(resultpath, name), 'wb')
            ftp.retrbinary('RETR %s'% (v), filehandler.write)
            filehandler.close()
            filehandler = None
            downlaodlist.append(os.path.join(resultpath, name))
            index += 1
    except Exception:
        logging.exception('ftp download error')
        if filehandler:
            filehandler.close()
    
    ftp.close()        
    return downlaodlist


def CaseResultParse(filelist):
    resultlist = []
    for v in filelist:
        parsetype =  re.findall(r'\((\w+)\)', v)
        logging.info(parsetype)
        if parsetype :
            try:
                parser = resultparse.GetParser(parsetype[0])
                result = parser(v)
                resultlist.extend(result)
            except Exception:
                logging.exception('parse test result fail')
        else:
            logging.warn('result filename not support')
    return resultlist



    